package com.homedo.odin.solution.service.common.impl;

import com.dangdang.ddframe.rdb.sharding.id.generator.IdGenerator;
import com.dangdang.ddframe.rdb.sharding.id.generator.self.IPIdGenerator;
import com.homedo.core.common.base.dto.Meta;
import com.homedo.core.common.exception.BizException;
import com.homedo.core.common.util.HttpClient;
import com.homedo.odin.solution.config.PaymentConfigHelper;
import com.homedo.odin.solution.enumcode.basic.BusinessTypeEnum;
import com.homedo.odin.solution.enumcode.pay.ReturnCode;
import com.homedo.odin.solution.enumcode.solution.SolutionStateEnum;
import com.homedo.odin.solution.enumcode.specification.SpecificationStatus;
import com.homedo.odin.solution.enumcode.user.PayStateEnum;
import com.homedo.odin.solution.model.entity.Solution;
import com.homedo.odin.solution.model.entity.Specification;
import com.homedo.odin.solution.model.entity.UserPayOrder;
import com.homedo.odin.solution.service.SolutionServiceImpl;
import com.homedo.odin.solution.service.SpecificationServiceImpl;
import com.homedo.odin.solution.service.UserPayOrderServiceImpl;
import com.homedo.odin.solution.service.common.PaymentService;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

/**
 * @author: zhaoxudong
 * @date: 2018/4/12 13:21
 * @Description:
 */
@Service
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    PaymentConfigHelper paymentConfig;
    @Autowired
    SolutionServiceImpl solutionService;
    @Autowired
    SpecificationServiceImpl specificationService;
    @Autowired
    UserPayOrderServiceImpl userPayOrderService;

    /**
     * 阿里支付 PC
     */
    @Override
    public String aliPayPc(Map<String, String> paraMap) {
        paraMap.put("CKey", paymentConfig.getCkey());
        String result = "";
        try {
            MultiValueMap<String, String> map = getMultiValueMap(paraMap);
            result = HttpClient.post(paymentConfig.getAlipayPcUrl(), map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 银联支付PC B2C
     */
    @Override
    public String unionPayB2CPc(Map<String, String> paraMap) {
        paraMap.put("CKey", paymentConfig.getCkey());
        String result = "";
        try {
            MultiValueMap<String, String> map = getMultiValueMap(paraMap);
            result = HttpClient.post(paymentConfig.getUnionpayB2CPcUrl(), map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 银联支付PC B2B
     */
    @Override
    public String unionPayB2BPc(Map<String, String> paraMap) {
        paraMap.put("CKey", paymentConfig.getCkey());
        String result = "";
        try {
            MultiValueMap<String, String> map = getMultiValueMap(paraMap);
            result = HttpClient.post(paymentConfig.getUnionpayB2BPcUrl(), map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 微信支付PC
     */
    @Override
    public String wxPayPc(Map<String, String> paraMap) {
        paraMap.put("CKey", paymentConfig.getCkey());
        String redirectUrl =
                paymentConfig.getRedirectUrl() + "?tradeNo=" + paraMap.get("OrderIds") + "&amount=" + paraMap
                        .get("Amount");
        paraMap.put("RedirectUrl", redirectUrl);
        String result = "";
        try {
            MultiValueMap<String, String> map = getMultiValueMap(paraMap);
            result = HttpClient.post(paymentConfig.getWxpayPcUrl(), map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 生成付款订单
     */
    @Override
    public String handlePayAmount(UserPayOrder userPayOrder) {
        String orderNo = null;
        if (BusinessTypeEnum.SOLUTION.getDbValue() == userPayOrder.getBusinessType().intValue()) {
            //方案
            Solution solution = solutionService.getSolution(userPayOrder.getBusinessId());
            if (solution == null) {
                throw new BizException(new Meta(ReturnCode.TARGET_NOT_FOUND.getValue(), "方案不存在"));
            }
            if (solution.getIsFree().intValue() == 0) {
                throw new BizException(new Meta(ReturnCode.TARGET_NOT_FOUND.getValue(), "该方案不收费"));
            }
            if (solution.getStatus().intValue() != SolutionStateEnum.SHELVE.getDbValue()) {
                throw new BizException(new Meta(ReturnCode.TARGET_NOT_FOUND.getValue(), "该方案不是上架状态"));
            }
//			if(SOLUTION.getCharges().compareTo(userPayOrder.getAmount()) !=0){
//				throw new SCInvalidParamException("付款金额和收费金额不匹配");
//			}
            if (solution.getUserId().equals(userPayOrder.getUid())) {
                throw new BizException(new Meta(ReturnCode.INVALID_PARAMS.getValue(), "当前用户为该方案上传用户！"));
            }
            String subject = "方案馆--" + solution.getSolutionName();
            UserPayOrder payOrder = userPayOrderService
                    .queryUserPayOrder(userPayOrder.getBusinessId(), userPayOrder.getUid());
            if (payOrder == null) {
                IdGenerator idGenerator = new IPIdGenerator();
                orderNo = idGenerator.generateId().toString();
                userPayOrder.setBusinessId(solution.getSolutionId());
                userPayOrder.setBusinessName(solution.getSolutionName());
                userPayOrder.setBusinessType(BusinessTypeEnum.SOLUTION.getDbValue());
                userPayOrder.setOrderNo(Long.valueOf(orderNo));
                userPayOrder.setPayContent(subject);
                userPayOrder.setCreateTime(new Date());
                userPayOrder.setStatus(PayStateEnum.WAITTOPAY.getDbValue());
                Integer insertCount = userPayOrderService.insertPayOrder(userPayOrder);
                if (insertCount == null) {
                    throw new BizException(new Meta(ReturnCode.SYS_ERR.getValue(), "生成支付订单失败！"));
                }
            } else {
                if (PayStateEnum.PAYCOMPLETE.getDbValue().equals(payOrder.getStatus())) {//支付完成
                    throw new BizException(new Meta(ReturnCode.TARGET_NOT_FOUND.getValue(), "该订单已经支付完成，不能重复支付！"));
                }

                if (!userPayOrder.getPayMode().equals(payOrder.getPayMode())) {//需要更新支付方式
                    int count = userPayOrderService.updatePayModel(payOrder.getOrderNo(), userPayOrder.getPayMode());
                    if (count == 0) {
                        throw new BizException(new Meta(ReturnCode.SYS_ERR.getValue(), "更新流水失败！"));
                    }
                }
                orderNo = payOrder.getOrderNo().toString();
            }
        } else if (BusinessTypeEnum.SPECIFICATION.getDbValue() == userPayOrder.getBusinessType().intValue()) {
            //行业规范
            Specification specification = specificationService.getSpecification(userPayOrder.getBusinessId());
            if (specification == null) {
                throw new BizException(new Meta(ReturnCode.TARGET_NOT_FOUND.getValue(), "行业规范不存在"));
            }
            if (specification.getCharges().compareTo(BigDecimal.ZERO) != 1) {
                throw new BizException(new Meta(ReturnCode.TARGET_NOT_FOUND.getValue(), "该行业规范不收费"));
            }
            if (specification.getStatus().intValue() != SpecificationStatus.SHELVE.getDbValue()) {
                throw new BizException(new Meta(ReturnCode.TARGET_NOT_FOUND.getValue(), "该行业规范不是上架状态"));
            }
//			if(specification.getCharges().compareTo(userPayOrder.getAmount()) !=0){
//				throw new SCInvalidParamException("付款金额和收费金额不匹配");
//			}
            if (userPayOrder.getUid().equals(specification.getUserId())) {
                throw new BizException(new Meta(ReturnCode.INVALID_PARAMS.getValue(), "当前用户为该方案上传用户！"));
            }
            String subject = "方案馆--" + specification.getSpecificationName();
            UserPayOrder payOrder = userPayOrderService
                    .queryUserPayOrder(userPayOrder.getBusinessId(), userPayOrder.getUid());
            if (payOrder == null) {
                IdGenerator idGenerator = new IPIdGenerator();
                orderNo = idGenerator.generateId().toString();
                userPayOrder.setBusinessId(specification.getSpecificationId());
                userPayOrder.setBusinessName(specification.getSpecificationName());
                userPayOrder.setBusinessType(BusinessTypeEnum.SPECIFICATION.getDbValue());
                userPayOrder.setOrderNo(Long.valueOf(orderNo));
                userPayOrder.setPayContent(subject);
                userPayOrder.setCreateTime(new Date());
                userPayOrder.setStatus(PayStateEnum.WAITTOPAY.getDbValue());
                Integer insertCount = userPayOrderService.insertPayOrder(userPayOrder);
                if (insertCount == null) {
                    throw new BizException(new Meta(ReturnCode.SYS_ERR.getValue(), "生成支付订单失败！"));

                }
            } else {
                if (PayStateEnum.PAYCOMPLETE.getDbValue().equals(payOrder.getStatus())) {//支付完成
                    throw new BizException(new Meta(ReturnCode.TARGET_NOT_FOUND.getValue(), "该订单已经支付完成，不能重复支付！"));
                }

                if (!userPayOrder.getPayMode().equals(payOrder.getPayMode())) {//需要更新支付方式
                    int count = userPayOrderService.updatePayModel(payOrder.getOrderNo(), userPayOrder.getPayMode());
                    if (count == 0) {
                        throw new BizException(new Meta(ReturnCode.SYS_ERR.getValue(), "更新流水失败！"));
                    }
                }
                orderNo = payOrder.getOrderNo().toString();
            }
        }

        return orderNo;
    }

    public static MultiValueMap<String, String> getMultiValueMap(Map<String, String> paramMap) {
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        if (paramMap != null && !paramMap.isEmpty()) {
            Set<String> keySet = paramMap.keySet();
            for (String key : keySet) {
                map.add(key, paramMap.get(key));
            }
        }

        return map;
    }

}
